import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';

import 'identify_bank_card.dart';
import 'identify_business_license.dart';
import 'identify_id_card.dart';

class BaiduAI {
  static const ACCESS_TOKEN_API = 'https://aip.baidubce.com/oauth/2.0/token';

  static const ID_CARD_API = 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard';

  static const BANK_CARD_API = 'https://aip.baidubce.com/rest/2.0/ocr/v1/bankcard';

  static const BUSINESS_LICENSE_API = 'https://aip.baidubce.com/rest/2.0/ocr/v1/business_license';

  static const API_KEY = 'GFRO7wuA33wB3FqvAvMTEUDh';

  static const SECRET_KEY = 'DAAEadV5Qxrfce2i6g0uGgo07IDbWPlQ';

  static String _accessToken;

  static Future<String> getAccessToken() async {
    if (_accessToken == null) {
      final dio = Dio();
      dio.interceptors.add(LogInterceptor(
        responseBody: true,
        requestBody: true,
      ));
      final res = await dio.post(ACCESS_TOKEN_API, queryParameters: {
        'grant_type': 'client_credentials',
        'client_id': API_KEY,
        'client_secret': SECRET_KEY,
      });
      if (res.statusCode == 200) {
        _accessToken = res.data['access_token'];
      }
    }

    return _accessToken;
  }

  static Future<IdentifyBusinessLicense> identifyBusinessLicense(File image) async {
    final base64 = await _image2Base64(image);

    final res = await _request(BUSINESS_LICENSE_API, {'image': base64, 'accuracy': 'high'});

    if (res.statusCode == 200) {
      return IdentifyBusinessLicense.fromJson(res.data);
    }

    return null;
  }

  static Future<IdentifyBankCard> identifyBankCard(File image) async {
    final base64 = await _image2Base64(image);

    final res = await _request(BANK_CARD_API, {'image': base64, 'accuracy': 'high'});

    if (res.statusCode == 200) {
      return IdentifyBankCard.fromJson(res.data);
    }

    return null;
  }

  static const ID_CARD_SIDE_FRONT = 'front';

  static const ID_CARD_SIDE_BACK = 'back';

  static Future<IdentifyIDCard> identifyIDCard(File image, String idCardSide) async {
    final base64 = await _image2Base64(image);

    final res = await _request(ID_CARD_API, {'image': base64, 'id_card_side': idCardSide});

    if (res.statusCode == 200) {
      return IdentifyIDCard.fromJson(res.data);
    }

    return null;
  }

  static _request(String url, Map<String, dynamic> data) async {
    final dio = Dio(BaseOptions(contentType: 'application/x-www-form-urlencoded'));
    dio.interceptors.add(LogInterceptor(
      responseBody: true,
      requestBody: true,
    ));
    final accessToken = await getAccessToken();

    return dio.post(url, data: data, queryParameters: {'access_token': accessToken});
  }

  static Future<String> _image2Base64(File image) async {
    final bytes = await image.readAsBytes();
    final base64 = base64Encode(bytes);

    return base64;
  }
}
